package com.killer.filter;

import com.alibaba.csp.sentinel.EntryType;
import com.alibaba.csp.sentinel.adapter.reactor.ContextConfig;
import com.alibaba.csp.sentinel.adapter.reactor.EntryConfig;
import com.alibaba.csp.sentinel.adapter.reactor.SentinelReactorTransformer;
import com.alibaba.csp.sentinel.adapter.spring.webflux.SentinelWebFluxFilter;
import com.alibaba.csp.sentinel.adapter.spring.webflux.callback.WebFluxCallbackManager;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MySentinelWebFluxFilter extends SentinelWebFluxFilter {


    private static final String EMPTY_ORIGIN = "";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        return chain.filter(exchange)
                .transform(buildSentinelTransformer(exchange));
    }

    private SentinelReactorTransformer<Void> buildSentinelTransformer(ServerWebExchange exchange) {
        //获取到url
        String path = exchange.getRequest().getPath().value();
        //处理restful风格url
        List<FlowRule> rules = new ArrayList<>();
        rules.add(new FlowRule("/user/user/info/{token}"));
        rules.add(new FlowRule("/user/user/register/{email}/{password}/{code}"));
        rules.add(new FlowRule("/user/user/isRegistered/{email}"));
        rules.add(new FlowRule("/user/user/login/{email}/{password} "));
        rules.add(new FlowRule("/code/code/create/{email}"));
        rules.add(new FlowRule("/code/code/validate/{email}/{code}"));
        rules.add(new FlowRule("/email/email/{email}/{code}"));
        RestfulUrlCleaner cleaner = RestfulUrlCleaner.create(rules);
        String finalPath = cleaner.clean(path);
        String origin = Optional.ofNullable(WebFluxCallbackManager.getRequestOriginParser())
                .map(f -> f.apply(exchange))
                .orElse(EMPTY_ORIGIN);

        return new SentinelReactorTransformer<>(
                new EntryConfig(finalPath, EntryType.IN, new ContextConfig(finalPath, origin)));
    }

}
